
using System;
using System.IO;
using System.Reflection;
using System.Resources;

namespace ScrewTurn.Wiki {

	/// <summary>
	/// Contains tools for creating files and directories at the first run.
	/// </summary>
	public static class StartupTools {

		/// <summary>
		/// Creates the data directories and files.
		/// </summary>
		/// <returns><b>Null</b> in case of success, the occurred <see cref="T:Exception" /> otherwise.</returns>
		public static Exception Startup() {
			// This try/catch block has the only purpose of letting the admin know
			// the reason why the wiki engine cannot startup
			try {
				// Setup Resource Exchanger
				Exchanger.ResourceExchanger = new ResourceExchanger();

				if(!File.Exists(Settings.LogFile)) {
					File.Create(Settings.LogFile).Close();
				}

				if(!File.Exists(Settings.ConfigFile)) {
					File.Create(Settings.ConfigFile).Close();
				}

				// Load config
				Settings.Init();

				// Load MIME Types
				MimeTypes.Init();

				if(!Directory.Exists(Settings.PagesDirectory)) {
					Directory.CreateDirectory(Settings.PagesDirectory);
					Log.LogEntry("PagesDirectory created", EntryType.General, "SYSTEM");
				}
				if(!Directory.Exists(Settings.MessagesDirectory)) {
					Directory.CreateDirectory(Settings.MessagesDirectory);
					Log.LogEntry("MessagesDirectory created", EntryType.General, "SYSTEM");
				}
				if(!Directory.Exists(Settings.SnippetsDirectory)) {
					Directory.CreateDirectory(Settings.SnippetsDirectory);
					Log.LogEntry("SnippetsDirectory created", EntryType.General, "SYSTEM");
				}
				if(!Directory.Exists(Settings.UploadDirectory)) {
					Directory.CreateDirectory(Settings.UploadDirectory);
					Log.LogEntry("UploadDirectory created", EntryType.General, "SYSTEM");
				}
				if(!Directory.Exists(Settings.TempDirectory)) {
					Directory.CreateDirectory(Settings.TempDirectory);
					Log.LogEntry("TempDirectory created", EntryType.General, "SYSTEM");
				}
				else {
					// Cleanup Temp files
					string[] files = Directory.GetFiles(Settings.TempDirectory);
					for(int i = 0; i < files.Length; i++) {
						try {
							File.Delete(files[i]);
						}
						catch { }
					}
				}

				if(!Directory.Exists(Settings.ThemesDirectory)) {
					Directory.CreateDirectory(Settings.ThemesDirectory);
					Log.LogEntry("ThemesDirectory created", EntryType.General, "SYSTEM");
				}
				if(!Directory.Exists(Settings.JsDirectory)) {
					Directory.CreateDirectory(Settings.JsDirectory);
					Log.LogEntry("JsDirectory created", EntryType.General, "SYSTEM");
				}
				if(!Directory.Exists(Settings.PluginsDirectory)) {
					Directory.CreateDirectory(Settings.PluginsDirectory);
					Log.LogEntry("PluginsDirectory created", EntryType.General, "SYSTEM");
				}
				if(!Directory.Exists(Settings.PluginsConfigurationDirectory)) {
					Directory.CreateDirectory(Settings.PluginsConfigurationDirectory);
					Log.LogEntry("PluginsConfigurationDirectory created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.PluginsStatusFile)) {
					File.Create(Settings.PluginsStatusFile).Close();
					Log.LogEntry("PluginsStatusFile created", EntryType.General, "SYSTEM");
				}

				if(!File.Exists(Settings.UsersFile)) {
					File.Create(Settings.UsersFile).Close();
					Log.LogEntry("UsersFile created", EntryType.General, "SYSTEM");
				}

				bool createMainPage = false;
				if(!File.Exists(Settings.PagesFile)) {
					File.Create(Settings.PagesFile).Close();
					createMainPage = true;
					Log.LogEntry("PagesFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.RecentChangesFile)) {
					File.Create(Settings.RecentChangesFile).Close();
					Log.LogEntry("RecentChangesFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.CategoriesFile)) {
					File.Create(Settings.CategoriesFile).Close();
					Log.LogEntry("CategoriesFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.NavigationPathsFile)) {
					File.Create(Settings.NavigationPathsFile).Close();
					Log.LogEntry("NavigationPathsFile created", EntryType.General, "SYSTEM");
				}

				if(!File.Exists(Settings.HtmlHeadFile)) {
					File.Create(Settings.HtmlHeadFile).Close();
					Log.LogEntry("HtmlHeadFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.HeaderFile)) {
					File.Create(Settings.HeaderFile).Close();
					Tools.WriteFile(Settings.HeaderFile, HeaderContent);
					Log.LogEntry("HeaderFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.SidebarFile)) {
					File.Create(Settings.SidebarFile).Close();
					Tools.WriteFile(Settings.SidebarFile, SidebarContent);
					Log.LogEntry("SidebarFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.FooterFile)) {
					File.Create(Settings.FooterFile).Close();
					Tools.WriteFile(Settings.FooterFile, FooterContent);
					Log.LogEntry("FooterFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.PageHeaderFile)) {
					File.Create(Settings.PageHeaderFile).Close();
					Log.LogEntry("PageHeaderFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.PageFooterFile)) {
					File.Create(Settings.PageFooterFile).Close();
					Log.LogEntry("PageFooterFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.AccountActivationMessageFile)) {
					File.Create(Settings.AccountActivationMessageFile).Close();
					Tools.WriteFile(Settings.AccountActivationMessageFile, AccountActivationMessageContent);
					Log.LogEntry("AccountActivationMessageFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.PasswordResetMessageFile)) {
					File.Create(Settings.PasswordResetMessageFile).Close();
					Tools.WriteFile(Settings.PasswordResetMessageFile, PasswordResetMessageContent);
					Log.LogEntry("PasswordResetMessageFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.EditNoticeFile)) {
					File.Create(Settings.EditNoticeFile).Close();
					Tools.WriteFile(Settings.EditNoticeFile, EditNoticeContent);
					Log.LogEntry("EditNoticeFile created", EntryType.General, "SYSTEM");
				}
				if(!File.Exists(Settings.LoginNoticeFile)) {
					File.Create(Settings.LoginNoticeFile).Close();
					Tools.WriteFile(Settings.LoginNoticeFile, "");
					Log.LogEntry("LoginNoticeFile created", EntryType.General, "SYSTEM");
				}

				// Load Host
				Host.Instance = new Host();

				// Load Providers
				Collectors.UsersProviderCollector = new ProviderCollector<ScrewTurn.Wiki.PluginFramework.IUsersStorageProvider>();
				Collectors.PagesProviderCollector = new ProviderCollector<ScrewTurn.Wiki.PluginFramework.IPagesStorageProvider>();
				Collectors.FormatterProviderCollector = new ProviderCollector<ScrewTurn.Wiki.PluginFramework.IFormatterProvider>();
				Collectors.DisabledUsersProviderCollector = new ProviderCollector<ScrewTurn.Wiki.PluginFramework.IUsersStorageProvider>();
				Collectors.DisabledPagesProviderCollector = new ProviderCollector<ScrewTurn.Wiki.PluginFramework.IPagesStorageProvider>();
				Collectors.DisabledFormatterProviderCollector = new ProviderCollector<ScrewTurn.Wiki.PluginFramework.IFormatterProvider>();

				DefaultLocalUsersStorageProvider u = new DefaultLocalUsersStorageProvider();
				u.Init(Host.Instance, "");
				if(!ProviderLoader.IsDisabled(u.GetType().ToString())) {
					Collectors.UsersProviderCollector.AddProvider(u);
					Log.LogEntry("Provider " + u.Information.Name + " loaded (Enabled)", EntryType.General, "SYSTEM");
				}
				else {
					Collectors.DisabledUsersProviderCollector.AddProvider(u);
					Log.LogEntry("Provider " + u.Information.Name + " loaded (Disabled)", EntryType.General, "SYSTEM");
				}
				DefaultLocalPagesStorageProvider p = new DefaultLocalPagesStorageProvider();
				p.Init(Host.Instance, "");
				if(!ProviderLoader.IsDisabled(p.GetType().ToString())) {
					Collectors.PagesProviderCollector.AddProvider(p);
					Log.LogEntry("Provider " + p.Information.Name + " loaded (Enabled)", EntryType.General, "SYSTEM");
				}
				else {
					Collectors.DisabledPagesProviderCollector.AddProvider(p);
					Log.LogEntry("Provider " + p.Information.Name + " loaded (Disabled)", EntryType.General, "SYSTEM");
				}

				ProviderLoader.FullLoad();

				// Load Snippets
				Snippets.Instance = new Snippets();

				// Load Pages
				Pages.Instance = new Pages();

				// Load Nav. Paths
				NavigationPaths.Instance = new NavigationPaths();

				// Load Users
				Users.Instance = new Users();

				// Create Collisions class
				Collisions.Instance = new Collisions();

				// Create Redirections class
				Redirections.Instance = new Redirections();

				// Load Recent Changes
				RecentChanges.Instance = new RecentChanges();

				// Create the Main Page, if needed
				if(createMainPage) CreateMainPage();

				Log.LogEntry("ScrewTurn Wiki is ready", EntryType.General, "SYSTEM");

				return null;
			}
			catch(Exception ex) {
				return ex;
			}
		}

		public static void CreateMainPage() {
			Pages.Instance.CreatePage("MainPage");
			Pages.Instance.ModifyPage(Pages.Instance.FindPage("MainPage"), "Main Page", "SYSTEM", DateTime.Now, "", MainPageContent, false);
		}

		public static void Shutdown() {
			// Performs shutdown operations, such as shutting-down Providers
			for(int i = 0; i < Collectors.FormatterProviderCollector.AllProviders.Length; i++) {
				Collectors.FormatterProviderCollector.AllProviders[i].Shutdown();
			}
			for(int i = 0; i < Collectors.PagesProviderCollector.AllProviders.Length; i++) {
				Collectors.PagesProviderCollector.AllProviders[i].Shutdown();
			}
			for(int i = 0; i < Collectors.UsersProviderCollector.AllProviders.Length; i++) {
				Collectors.UsersProviderCollector.AllProviders[i].Shutdown();
			}
		}

		private static string MainPageContent = @"Welcome to '''{WIKITITLE}'''!{BR}
This is the main page of your new ScrewTurn Wiki, created for you by the system.

You should [Edit.aspx?Page=MainPage|edit this page] and customize the contents. You can also [Edit.aspx|create a new page] from scratch.

If you need help, try to visit [http://www.screwturn.eu|our website] or [http://www.screwturn.eu/forum|our forum].

'''Warning''': remember to setup the ''admin'' account by editing the {{Web.config}} file placed in the root directory of the Wiki. It is ''extremely dangerous'' to keep the default password.";

		private static string AccountActivationMessageContent = @"Hi ##USERNAME## and welcome to ##WIKITITLE##!
You must activate your new ##WIKITITLE## Account within 24 hours, following the link below.

##ACTIVATIONLINK##

If you have any trouble, please contact us at our Email address, ##EMAILADDRESS## .

Thank you.

Best regards,
The ##WIKITITLE## Team.
";

		private static string EditNoticeContent = @"Please '''do not''' include contents covered by copyright without the explicit permission of the Author. Always preview the result before saving.{BR}
If you are having trouble, please visit the [http://www.screwturn.eu/Help.aspx|Help section] at [http://www.screwturn.eu|ScrewTurn Software].";

		private static string FooterContent = @"<p class=""small"">[http://www.screwturn.eu|ScrewTurn Wiki] version {WIKIVERSION}. Some of the icons created by [http://www.famfamfam.com|FamFamFam].</p>";

		private static string HeaderContent = @"<h1>{WIKITITLE}</h1>";

		private static string PasswordResetMessageContent = @"Hi ##USERNAME##!
Your password has been reset. Your new Password is:
    ##PASSWORD##

After you login, you'll be able to change it.
If you have any trouble, please contact us at our Email address, ##EMAILADDRESS## .

Thank you.

Best regards,
The ##WIKITITLE## Team.
";

		private static string SidebarContent = @"<div style=""float: right;""><a href=""RSS.aspx"" title=""Update notifications for {WIKITITLE} (RSS 2.0)""><img src=""{THEMEPATH}Images/RSS.png"" alt=""RSS"" /></a></div>
====Navigation====
* '''[MainPage|Main Page]'''

* [RandPage.aspx|Random Page]
* [Edit.aspx|Create a new Page]
* [AllPages.aspx|All Pages]
* [Category.aspx|Categories]

* [Admin.aspx|Administration]
* [Upload.aspx|File Management]

* [Login.aspx|Login/Logout]
* [Language.aspx|Language Selection]
* [Profile.aspx|Your Profile]
* [Register.aspx|Create Account]

<small>'''Quick Search'''</small>{BR}
{SEARCHBOX}{BR}
<small>[Search.aspx?FullText=1|Advanced Search &raquo;]</small>

[image|PoweredBy|Images/PoweredBy.png|http://www.screwturn.eu]";

	}

}
